package com.ccx.library.util;

import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.DefaultClock;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;

public class JwtProvide {

    private static String secret="ccxGradBack-666-wzt-[bb]";
    private static long expire=36000;

    private Clock clock = DefaultClock.INSTANCE;

    /**
     * 使用用户名作为身份信息生成Token
     */
    public static Map getToken(Map<String,Object> sub) {
        Date nowDate = new Date();
        //token过期时间
        long expireAt=nowDate.getTime() + expire * 1000;
        Date expireDate = new Date(expireAt);
        Map map=new HashMap<>();
//        map.put("expireAt",expireAt);
        String token= Jwts.builder()
                //放入唯一标识,可以是用户名或者Id
                .setSubject((String) sub.get("username"))
                .setClaims(sub)
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(SignatureAlgorithm.HS256, secret)
                .compact();
        String s = UUID.randomUUID().toString();
        map.put("token",token);
        map.put("code",200);
        map.put("key", s);
        return map;
    }

    /**
     * 根据token获取身份信息
     */
    public static Claims getTokenClaim(String token) {
        try {
            return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        }catch (ExpiredJwtException e){
            return e.getClaims();
        }
    }

    /**
     * 判断token是否失效
     */
    public boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(clock.now());
    }

    /**
     * 根据token获取username
     */
    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }

    /**
     * 根据token获取失效时间
     */
    public Date getExpirationDateFromToken(String token) {
        return getClaimFromToken(token, Claims::getExpiration);
    }

    public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = getTokenClaim(token);
        return claimsResolver.apply(claims);
    }
}
